package org.directfire.player;

import java.util.ArrayList;
import java.util.List;
import org.directfire.player.model.Model;
import org.directfire.player.utils.DFException;
import org.directfire.player.utils.DFPagerAdapter;
import org.directfire.player.utils.NotificationUtils;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.SimpleOnPageChangeListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
/**
 *   Copyright (C) 2012 Alexey Kostrjitskiy mailto:alex@ipss.net
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 * $Id: ApplicationActivity.java 35 2012-08-31 16:23:54Z alexeyvk@gmail.com $<br/>
 * $HeadURL: http://directfire.googlecode.com/svn/branches/0.1/DirectFireAndroid/src/org/directfire/player/ApplicationActivity.java $<br/><br/>
 *
 * Main activity of the DirectFirePlayer.
 */
public class ApplicationActivity extends FragmentActivity{
	/** Messenger for communicating with service. */
	private Messenger mService = null;
	/** Flag indicating whether we have called bind on the service. */
	private boolean mIsBound;
	/** Model instance */
	private static Model mdl = Model.getI();
  /** system audio manager */
  private AudioManager mgr = null;
  /** receiver for volume button events */
  //ComponentName mVolCr=null;
	/** used to show exception  dialog */
	private DialogFragment errorD=null;
	/** internal counter for volumebar fade in seconds*/
	private static int volumeFadeSecsCounter=DirectFireService.defaultVolumeBarFadeSeconds;
	/** animation for logo */
	private static Animation rotate=AnimationUtils.loadAnimation(DirectFire.getContext(), R.anim.rotate_picture);


	/** View for main player page - PLAYER*/
  private View pPlayer;
	/** View for schedule page 		- SCHEDULE*/  
  private View pSchedule;
	/** View for news page 				- NEWS*/  
  private View pNews;
  /** reference to ViewPager*/
  private ViewPager mPager;
  /** our page adapter for ViewPager*/
  private DFPagerAdapter mPagerAdapter;
  ///** title page indicator */
  //private TitlePageIndicator mTitleIndicator;
  /** page change listener internal class */
  private DFPageListener	pgListener = new DFPageListener();

  
  @Override
  /** onCreate method of the main activity. Also activity recreated when device orientation changed */    
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    setTitle(getResources().getString(R.string.app_name)+" "+getResources().getString(R.string.versionName));
    doBindService();
    setVolumeControlStream(AudioManager.STREAM_MUSIC);    
  	mgr=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
  	//mVolCr = new ComponentName(this, VolumeControlReceiver.class);
  	//((AudioManager)getSystemService(AUDIO_SERVICE)).registerMediaButtonEventReceiver(mVolCr);
		((RelativeLayout)findViewById(R.id.titlebar_layout)).setOnTouchListener(pTitleBarToucEvent);
  	
    LayoutInflater inflater = LayoutInflater.from(this);
    pPlayer = inflater.inflate(R.layout.pg_view0_player, null);
    pPlayer.setTag(getString(R.string.tag_player));
    pPlayer.setOnTouchListener(pPlayerToucEvent);
		((SeekBar)pPlayer.findViewById(R.id.volume_seek)).setOnTouchListener(pPlayerToucEvent);
    pSchedule = inflater.inflate(R.layout.pg_view1_schedule, null);
    pSchedule.setTag(getString(R.string.tag_schedule));
    pNews = inflater.inflate(R.layout.pg_view2_news, null);
    pNews.setTag(getString(R.string.tag_news));
    
    List<View> mPages = new ArrayList<View>();
    mPages.add(pPlayer);
    mPages.add(pSchedule);
    mPages.add(pNews);
    mPagerAdapter = new DFPagerAdapter(mPages);
    mPager = (ViewPager) findViewById(R.id.viewpager);
    mPager.setAdapter(mPagerAdapter);
    mPager.setCurrentItem(DFPagerAdapter.VIEW0_PLAYER);
    mPager.setOnPageChangeListener(pgListener);
    //mTitleIndicator = (TitlePageIndicator) findViewById(R.id.viewpagerindicator);
    //mTitleIndicator.setViewPager(mPager);
    //mTitleIndicator.setCurrentItem(DFPagerAdapter.VIEW0_PLAYER);
    //mTitleIndicator.setOnPageChangeListener(pgListener);
    
  	SeekBar vlm = (SeekBar)pPlayer.findViewById(R.id.volume_seek);
  	vlm.setMax(mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC)*100);
  	vlm.setProgress(mgr.getStreamVolume(AudioManager.STREAM_MUSIC)*100);
  	mdl.setDuckVolume(mgr.getStreamVolume(AudioManager.STREAM_MUSIC));
  	vlm.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
			public void onStopTrackingTouch(SeekBar seekBar) {}
			public void onStartTrackingTouch(SeekBar seekBar) {	}
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
				mgr.setStreamVolume(AudioManager.STREAM_MUSIC, progress/100, AudioManager.FLAG_PLAY_SOUND);
			}
		});
  }

	@Override
  /** onDestroy method, when activity finished */
	public void onDestroy (){
		super.onDestroy();
		doUnbindService();
  	//((AudioManager)getSystemService(AUDIO_SERVICE)).unregisterMediaButtonEventReceiver(mVolCr);
	}
  
  @Override
  /** Called when the activity is resumed. */
  public void onResume(){
  	super.onResume();
  	DirectFire.setActivity(this);
  	
		ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		if(cm.getActiveNetworkInfo()==null || cm.getActiveNetworkInfo().isConnected()==false){
			Toast.makeText(this, getResources().getString(R.string.trs_no_connectivity), Toast.LENGTH_LONG).show();
			mdl.setNoConnectivity(true);
		}else
			mdl.setNoConnectivity(false);
		if(mdl.getCurrent_flow() != mPager.getCurrentItem())
				mPager.setCurrentItem(mdl.getCurrent_flow());
		updateStatus();
  }
  
  /** Called when the activity is switched away. */
  @Override
  public void onPause() {
  	super.onPause();
  	DirectFire.setActivity(null);
  }
  
  /** update system hidden titlebar and state textview */
  @Override
  public void setTitle(CharSequence title) {
  	super.setTitle(title);
  	TextView state = (TextView) findViewById(R.id.title);  	
  	state.setText(title); 
  }

  OnTouchListener pTitleBarToucEvent = new OnTouchListener() {
		public boolean onTouch(View v, MotionEvent event) {
	  	doDFScommand(DirectFireService.DFS_STOP, null);
	 		v.playSoundEffect(SoundEffectConstants.CLICK);
	 		return false;
		}
	};

  OnTouchListener pPlayerToucEvent = new OnTouchListener() {
		public boolean onTouch(View v, MotionEvent event) {
			final SeekBar sb = (SeekBar)pPlayer.findViewById(R.id.volume_seek);
			sb.setVisibility(View.VISIBLE);
			mHandler.removeMessages(DirectFireService.MSG_FADE_OUT);
			volumeFadeSecsCounter=DirectFireService.defaultVolumeBarFadeSeconds-2;
	 		Message msg = Message.obtain(null, DirectFireService.MSG_FADE_OUT);
	 		mHandler.sendMessageDelayed(msg, 1000);
	 		//v.playSoundEffect(SoundEffectConstants.CLICK);
	 		return false;
		}
	};
	
  @Override
	/** parent view touch event dispatched at top level. */
	public boolean dispatchTouchEvent(MotionEvent event){
		return super.dispatchTouchEvent(event);
	}

 /** when hardware Back button pressed */ 
  @Override
	public void onBackPressed(){
  	moveTaskToBack(false);
	}

	/** listener for ViewPage switching */
  private class DFPageListener extends SimpleOnPageChangeListener{
    public void onPageSelected(int position) {
			mdl.setCurrent_flow(position);
			switch(position){
			 case DFPagerAdapter.VIEW0_PLAYER:
				break;
			 case DFPagerAdapter.VIEW1_SCHEDULE:
				break;
			 case DFPagerAdapter.VIEW2_NEWS:
				break;
			 default:
			}
		}
  }
  
  /** Click event for play button */ 
  public void onPlayClick(View view) {
  	Bundle b = new Bundle();
  	switch(view.getId()){
  		case R.id.button_play0:
  			b.putInt("station", 0);
  			doDFScommand(DirectFireService.DFS_PLAY, b);		
  			break;
  		case R.id.button_play1:
  			b.putInt("station", 1);
  			doDFScommand(DirectFireService.DFS_PLAY, b);		
  			break;
  		case R.id.button_play2:
  			b.putInt("station", 2);
  			doDFScommand(DirectFireService.DFS_PLAY, b);		
  			break;
  		/*case R.id.button_play3:
  			b.putInt("station", 3);
  			doDFScommand(DirectFireService.DFS_PLAY, b);		
  			break;
  		case R.id.button_play4:
  			b.putInt("station", 4);
  			doDFScommand(DirectFireService.DFS_PLAY, b);		
  			break;
  		case R.id.button_play5:
  			b.putInt("station", 5);
  			doDFScommand(DirectFireService.DFS_PLAY, b);		
  			break;*/
  	}
  	
  }

  /** Click event for layout temporary debug button - logo */ 
  public void onStopClick(View view) {
  	doDFScommand(DirectFireService.DFS_STOP, null);
  	view.playSoundEffect(SoundEffectConstants.CLICK);
  }

	@Override
	/** When activity options menu created */
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater menuInflater = getMenuInflater();
		menuInflater.inflate(R.menu.main, menu);
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	/** Before options menu displayed */
	public boolean onPrepareOptionsMenu (Menu menu){
		//MenuItem exit = menu.findItem(R.id.menu_exit);
		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	/** When options menu selected */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
     case R.id.menu_exit:
    	 exitWithConfirm();
    	 break;
     default:
     	 break;
    }
		return super.onOptionsItemSelected(item);
	}

	/** Update visual content */
	private void updateStatus(){
		final SeekBar vlm = (SeekBar)pPlayer.findViewById(R.id.volume_seek);
  	vlm.setProgress(mgr.getStreamVolume(AudioManager.STREAM_MUSIC)*100);
  	//ImageButton stopB = (ImageButton)pPlayer.findViewById(R.id.button_stop);
  	//stopB.setVisibility(mdl.isPlaying()?View.VISIBLE:View.GONE );
		final ImageView   sb = (ImageView)findViewById(R.id.status_button);
		final ProgressBar pb = (ProgressBar)findViewById(R.id.progress_button);
		if(mdl.isNoConnectivity()){
  		sb.setAnimation(null);
			sb.setVisibility(View.GONE);
			pb.setVisibility(View.VISIBLE);
		}else{
			sb.setVisibility(View.VISIBLE);
			pb.setVisibility(View.GONE);
			if(mdl.isPlaying())
	  		sb.startAnimation(rotate);
	  	else{
	  		rotate.cancel();
	  		sb.setAnimation(null);
	  	}
		}
  	setTitle(mdl.getFullTitle());
  }

  /** send command to service */
	private void doDFScommand(int command, Bundle b){
		Message msg=Message.obtain(null, command);
		if(b!=null)
			msg.setData(b);
		msg.replyTo = mMessenger;
		if(mIsBound)
			try {
				mService.send(msg);
			} catch (RemoteException e) {
				throw mdl.exception(e, 402);
			}
	}

  /** Handler of incoming messages from service. */
	static class DFServiceIncomingHandler extends Handler {
		/** activity reference */
		private ApplicationActivity act;
		
		/** public constructor for our activity */
		public DFServiceIncomingHandler(FragmentActivity act){
			this.act = (ApplicationActivity)act;
		}
		
    @Override
    public void handleMessage(Message msg) {
    	switch (msg.what) {
    	 case DirectFireService.MSG_FADE_OUT:
    		if(volumeFadeSecsCounter==0){
    			final SeekBar sb = (SeekBar)act.pPlayer.findViewById(R.id.volume_seek);
    			sb.setVisibility(View.GONE);
    		}else{
    			Message m = Message.obtain(null, DirectFireService.MSG_FADE_OUT);
    			sendMessageDelayed(m, 1000);
    			volumeFadeSecsCounter--;
    		}
   			break;
    	 case DirectFireService.MSG_EVENT_SERVICE_STOPPED:
    		act.finish();
				break;
       case DirectFireService.MSG_EVENT_CONN_LOST:
      	Toast.makeText(act, String.format(act.getResources().getString(R.string.trs_netconnection_failed), 
      			((NetworkInfo)msg.getData().getParcelable("current")).getTypeName().toUpperCase() ), Toast.LENGTH_LONG).show();
 				NotificationUtils.getInstance().soundNotification(NotificationUtils.SOUND_DISCONNECTED);
      	break;
      case DirectFireService.MSG_EVENT_CONN_RESTORED:
      	Toast.makeText(act, String.format(act.getResources().getString(R.string.trs_netconnection_restored),
      			((NetworkInfo)msg.getData().getParcelable("current")).getTypeName().toUpperCase() ), Toast.LENGTH_LONG).show();
 				NotificationUtils.getInstance().soundNotification(NotificationUtils.SOUND_CONNECTED);
      	break;
      case DirectFireService.MSG_EVENT_TITLE_CNAGED:
      case DirectFireService.MSG_AUDIO_BECOMING_NOISY:
      case DirectFireService.MSG_AUDIO_STARTED:
      case DirectFireService.MSG_AUDIO_STOPPED:
      case DirectFireService.MSG_EVENT_CONN_CHANGED:
      	break;
      case DirectFireService.MSG_EVENT_EXCEPTION:
    		if(DirectFire.getActivity()!=null){ 
    			if(DirectFire.getActivity().equals(act)){
    				act.showErrorDialog((DFException)msg.getData().getParcelable("exception"));
          }
    		}	
      	break;
      default:
      	super.handleMessage(msg);
      }
    	act.updateStatus();
    }
  }
	
	/** exit dialog */
	private void exitWithConfirm(){
		Dialog alert = new AlertDialog.Builder(ApplicationActivity.this)
			.setTitle(getResources().getText(R.string.trs_exitdialog_title))
			.setMessage(getResources().getText(R.string.trs_exitdialog_message))
			.setIcon(android.R.drawable.ic_dialog_info)
			.setPositiveButton(getResources().getText(R.string.trs_yes), new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					doDFScommand(DirectFireService.DFS_STOP_SERVICE, null);
			}})
			.setNegativeButton(getResources().getText(R.string.trs_no), null)
			.create();
		alert.show();
	}
	
	/** dismiss all dialogfragments */
	private void hideAllDialogs(){
		hideErrorDialog();
	}
	
  //
  //================================ ErrorDialog fragment  ===================
  //
  /** show exception dialog */
  void showErrorDialog(DFException e) {
  	hideAllDialogs();
  	if(errorD!=null)
  		errorD.dismissAllowingStateLoss();
  	errorD = ErrorDialog.newInstance(R.string.trs_exception_title, e);
  	errorD.show(getSupportFragmentManager(), "ErrorDialog");
  }
  
  /** hide exception dialog */
  void hideErrorDialog() {
  	if(errorD!=null)
  		errorD.dismissAllowingStateLoss();
  }  
  
  /** exception dialog fragment class */
  public static class ErrorDialog extends DialogFragment {
  	public static ErrorDialog newInstance(int title, DFException e) {
  		ErrorDialog frag = new ErrorDialog();
      Bundle args = new Bundle();
      args.putInt("title", title);
      args.putParcelable("exception", e);
      frag.setArguments(args);
      return frag;
  	}
  	@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
      int title = getArguments().getInt("title");
      DFException e = getArguments().getParcelable("exception");
      AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
      dialog.setTitle(title)
      .setMessage(e.toString())
 			.setPositiveButton((String)getResources().getText(R.string.trs_ok), null);
      dialog.setIcon(android.R.drawable.ic_dialog_alert);
 			return dialog.create();
    }
  }

  //
  //================== This is a default part of service interaction for activity =================
  //
  /** Target we publish for clients to send messages to IncomingHandler.  */
  private DFServiceIncomingHandler mHandler = new DFServiceIncomingHandler(this);
	public final Messenger mMessenger = new Messenger(mHandler);
  /** Class for interacting with the main interface of the service. */
  private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className,
          IBinder service) {
      mService = new Messenger(service);
      mIsBound = true;
      doDFScommand(DirectFireService.DFS_REGISTER_CLIENT, null);
    }
    public void onServiceDisconnected(ComponentName className) {
      // This is called when the connection with the service has been
      // unexpectedly disconnected -- that is, its process crashed.
    	unbindService(this);
      mService = null;
      mIsBound = false;
    }
  };
  
  /** bind service to this activity */
  private void doBindService() {
  	Intent WTS= new Intent(this, DirectFireService.class);
  	startService(WTS);
  	bindService(WTS, mConnection, Context.BIND_IMPORTANT);
  }
  /** unbind service from this activity */
  private void doUnbindService() {
  	if (mIsBound) {
      if (mService != null)
        doDFScommand(DirectFireService.DFS_UNREGISTER_CLIENT, null);     
      unbindService(mConnection);
    }
  }
}
